class ParticlesGravity1 extends egret.DisplayObjectContainer {
    private particles: Array<Ball>
    private numParticles: number = 30

    public constructor() {
        super()
        this.once( egret.Event.ADDED_TO_STAGE, this.onAddToStage, this)
    }

    private onAddToStage():void {
        this.particles = new Array<Ball>()
        for (let i = 0; i < this.numParticles; ++i) {
            let particle = new Ball(5)
            particle.x = Math.random() * this.stage.stageWidth
            particle.y = Math.random() * this.stage.stageHeight
            particle.mass = 1
            this.particles.push(particle)
            this.addChild(particle)
        }

        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this)
    }

    private onEnterFrame() {
        for (let part of this.particles) {
            part.x += part.vx
            part.y += part.vy
        }

        for (let i = 0; i < this.numParticles - 1; ++i) {
            let partA = this.particles[i]
            for (let j = i + 1; j < this.numParticles; ++j) {
                let partB = this.particles[j]
                this.gravitate(partA, partB)
            }
        }
    }

    private gravitate(partA:Ball, partB:Ball) {
        let dx = partB.x - partA.x
        let dy = partB.y - partA.y
        let distSQ = dx * dx + dy * dy
        let dist = Math.sqrt(distSQ)
        let force = partA.mass * partB.mass / distSQ
        let ax = force * dx / dist //  dx / dist == cos(angle)
        let ay = force * dy / dist //  dy / dist == sin(angle)
        partA.vx += ax / partA.mass
        partA.vy += ay / partA.mass
        partB.vx -= ax / partB.mass
        partB.vy -= ay / partB.mass
    }
}